package bb.lanxing.fragment.routebook;

import static bb.lanxing.common.config.Constants.REQUEST_CODE;
import static bb.lanxing.common.config.Constants.REQUEST_CODE_SEGMENT_MINE;
import static bb.lanxing.fragment.routebook.RouteBookFragment.INTENT_TYPE;
import static bb.lanxing.fragment.routebook.RouteBookFragment.INTENT_TYPE_NORMAL;
import static bb.lanxing.fragment.routebook.RouteBookFragment.INTENT_TYPE_SHARE;
import static bb.lanxing.manager.SPConstant.KEY_LU_SHU;
import static bb.lanxing.manager.SPConstant.KEY_SERVER_ID;

import java.util.LinkedList;
import java.util.List;

import android.app.Activity;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.os.Parcelable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListView;

import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.RequiresApi;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;

import bb.lanxing.R;
import bb.lanxing.activity.routebook.RouteBookInfoActivity;
import bb.lanxing.activity.sport.SportActivity;
import bb.lanxing.adapter.RouteBookNormalAdapter;
import bb.lanxing.common.config.Constants;
import bb.lanxing.device.thirdpart.gpx.GPXImportActivity;
import bb.lanxing.fragment.base.BaseViewFragment;
import bb.lanxing.model.database.RouteBook;
import bb.lanxing.model.page.PageInfo;
import bb.lanxing.util.BusProvider;
import bb.lanxing.util.RouteBookUtil;
import bb.lanxing.view.BiciAlertDialogBuilder;

public abstract class RouteBookListFragmentNew extends BaseViewFragment {
    private static final int CREATE_ROUTE_BOOK_REQUEST = 1;
    protected final List<RouteBook> routeBookList = new LinkedList<>();
    private final ActivityResultLauncher<String> getGpxLauncher =
            registerForActivityResult(new ActivityResultContracts.GetContent(), uri -> {
                if (uri != null) {
                    GPXImportActivity.Companion.launch(RouteBookListFragmentNew.this.requireContext(), uri);
                }
            });
    private final PageInfo pageInfo;
    protected RouteBookNormalAdapter adapter;
    protected View emptyBackground;
    protected ListView listView;
    private SwipeRefreshLayout refreshView;
    private boolean fromSportMap = false;
    private int intentType = INTENT_TYPE_NORMAL;

    public RouteBookListFragmentNew() {
        super();
        pageInfo = new PageInfo();
    }

    public int getPage() {
        return pageInfo.getPage();
    }

    protected void updatePage() {
        pageInfo.nextPage();
    }

    protected void resetPage() {
        pageInfo.reset();
    }

    protected int getPageSize() {
        return pageInfo.getPageSize();
    }

    @RequiresApi(api = Build.VERSION_CODES.TIRAMISU)
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null) {
            intentType = getArguments().getInt(INTENT_TYPE);
            fromSportMap = getArguments().getBoolean(RouteBookFragment.FROM_SPORT_MAP);
        }
        BusProvider.getInstance().register(this);
    }

    @Override
    public void onDetach() {
        super.onDetach();
        BusProvider.getInstance().unregister(this);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View inflate = inflater.inflate(R.layout.fragment_lushu_list, container, false);
        bindView(inflate);
        initHeader();
        adapter = getLushuNormalAdapter(routeBookList);
        adapter.setFromSportMap(fromSportMap);
        adapter.setOnLoadEndListener(this::loadMoreEvent);
        listView.setAdapter(adapter);
        listView.setOnItemClickListener((parent, view, position, id) -> {
            Intent intent;
            RouteBook routeBook = routeBookList.get(position);
            if (intentType == INTENT_TYPE_NORMAL) {
                intent = getIntent(routeBook);
                Long lushuId = routeBook.getId();
                if (null != lushuId) {
                    intent.putExtra(SportActivity.EXTRA_LUSHU_ID, lushuId);
                }
                long serverId = routeBook.getServerId();
                if (0 != serverId) {
                    intent.putExtra(KEY_SERVER_ID, serverId);
                }
                startActivityForResult(intent, REQUEST_CODE);
            } else if (intentType == INTENT_TYPE_SHARE) {
                confirmShare(routeBook);
            }
        });
        refreshView.setOnRefreshListener(this::requestData);
        autoRefresh();
        refresh();
        return inflate;
    }

    protected void initHeader() {
    }

    private void processActivityResult(int requestCode, int resultCode, Intent data) {
        if (resultCode == Constants.RESULT_CODE_LUSHU_EDIT || resultCode == Constants.RESULT_CODE_LUSHU_DELETE) {
            requestData();
        }
    }

    @Override
    public void autoRefresh() {
        if (refreshView != null) {
            refreshView.postDelayed(this::requestData, 100L);
        }
    }

    @Override
    public void refreshComplete() {
        adapter.setLoadingMoreFinished();
        if (getActivity() != null) {
            getActivity().runOnUiThread(() -> {
                if (refreshView != null) {
                    refreshView.setRefreshing(false);
                }
            });
        }
    }

    public abstract void requestData();

    protected void showLushuCreateDialog() {
        if (getActivity() == null) {
            return;
        }
        RouteBookUtil.showRouteBookCreateDialog(getContext(), this, CREATE_ROUTE_BOOK_REQUEST, getGpxLauncher);
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == CREATE_ROUTE_BOOK_REQUEST && resultCode == Activity.RESULT_OK) {
            RouteBookUtil.showDialogForCreatedLushu(getContext());
            autoRefresh();
        } else if (requestCode == Constants.REQUEST_CODE_FRAGMENT) {
            autoRefresh();
        } else if (requestCode != REQUEST_CODE_SEGMENT_MINE) {
            processActivityResult(resultCode, resultCode, data);
        }
    }

    public void confirmShare(final RouteBook routeBook) {
        new BiciAlertDialogBuilder(getActivity())
                .setMessage(getString(R.string.dialog_content_share_lushu, routeBook.getTitle()))
                .setNegativeButton(R.string.dialog_btn_no, null)
                .setPositiveButton(R.string.dialog_btn_share, (dialog, which) -> {
                    showLoadingDialog(R.string.dialog_content_processing, true, null);
                    new Thread(() -> {
                        Intent intent = new Intent();
                        long serverId = routeBook.getServerId();
                        String uuid = routeBook.getUuid();
                        String title = routeBook.getTitle();
                        intent.putExtra(KEY_SERVER_ID, serverId);
                        intent.putExtra("lushu_uuid", uuid);
                        intent.putExtra("lushu_title", title);
                        getActivity().setResult(-1, intent);
                        dismissLoadingDialog();
                        getActivity().finish();
                    }).start();
                }).show();
    }

    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        if (isVisibleToUser) {
            refresh();
        }
    }

    public void refresh() {
    }

    private void bindView(View bindSource) {
        listView = bindSource.findViewById(R.id.listView);
        refreshView = bindSource.findViewById(R.id.refreshView);
        emptyBackground = bindSource.findViewById(R.id.emptyBackground);
        View makeLushu = bindSource.findViewById(R.id.makeLushu);
        makeLushu.setOnClickListener(view -> showLushuCreateDialog());
    }

    public void refreshUIWithServer(final List<RouteBook> remoteRouteBookList, final boolean needClean) {
        if (getActivity() != null) {
            getActivity().runOnUiThread(() -> {
                boolean isEmpty = remoteRouteBookList.isEmpty();
                int len = remoteRouteBookList.size();
                setEmptyBackground(isEmpty);
                if (needClean) {
                    routeBookList.clear();
                }
                boolean loadMoreEnabled = len >= getPageSize();
                adapter.setLoadMoreEnabled(loadMoreEnabled);
                if (loadMoreEnabled) {
                    updatePage();
                }
                routeBookList.addAll(remoteRouteBookList);
                adapter.notifyDataSetChanged();
                refreshComplete();
            });
        }
    }

    protected RouteBookNormalAdapter getLushuNormalAdapter(List<RouteBook> routeBookList) {
        return new RouteBookNormalAdapter(getActivity(), routeBookList);
    }

    protected Intent getIntent(RouteBook routeBook) {
        Intent intent = new Intent(getActivity(), RouteBookInfoActivity.class);
        intent.putExtra(KEY_LU_SHU, (Parcelable) routeBook);
        return intent;
    }

    protected void setEmptyBackground(boolean isEmpty) {
    }

    protected void loadMoreEvent() {
    }
}